package team.seekers.hula.message.message.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import team.seekers.hula.common.entity.PageResult;
import team.seekers.hula.common.entity.enums.TunnelStatusEnum;
import team.seekers.hula.auth.service.MindUtils;
import team.seekers.hula.common.utils.ParamCheckUtils;
import team.seekers.hula.message.message.dao.MessageDao;
import team.seekers.hula.message.message.entity.dto.*;
import team.seekers.hula.message.message.entity.vo.MessageListVO;
import team.seekers.hula.message.message.entity.vo.MessageReplyListVO;
import team.seekers.hula.message.message.mapper.MessageMapper;
import team.seekers.hula.message.tunnel.dao.TunnelDao;
import team.seekers.hula.message.tunnel.entity.dao.TunnelDO;
import team.seekers.hula.question.question.service.QuestionService;
import team.seekers.hula.message.message.entity.dao.MessageDO;
import team.seekers.hula.user.user.entity.dao.UserDO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import team.seekers.hula.user.user.service.UserService;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * <p>
 * 消息通知表 服务实现类
 * </p>
 *
 * @author hbc
 * @since 2021-02-22
 */
@Service
public class MessageService extends ServiceImpl<MessageMapper, MessageDO> {

    private boolean result;

    @Autowired
    private UserService userService;

    @Autowired
    private QuestionService questionService;

    @Autowired
    private TunnelDao tunnelDao;

    @Autowired
    private MessageDao messageDao;

    public String add(MessageAddDTO addVO) {
        MessageDO messageDO = new MessageDO();
        BeanUtils.copyProperties(addVO, messageDO);
        messageDO.setFromId(MindUtils.getUserId());
        save(messageDO);
        return messageDO.getId();
    }

    public PageResult<MessageReplyListVO> pageOrderByTime(long current, long limit, MessageQueryDTO messageQueryDTO) {
        Page<MessageDO> page = new Page<>(current,limit);
        QueryWrapper<MessageDO> wrapper = new QueryWrapper<>();
        wrapper.eq("tunnel_id", messageQueryDTO.getTunnel());
        if(messageQueryDTO != null){
            String fromId = messageQueryDTO.getFromId();
            if(!StringUtils.isEmpty(fromId)){
                if(ParamCheckUtils.isNotRightId(fromId)){
                    return null;
                }
                wrapper.like("from_id",fromId);
            }
            String toId = messageQueryDTO.getToId();
            if (!StringUtils.isEmpty(toId)){
                if(ParamCheckUtils.isNotRightId(toId)){
                    return null;
                }
                wrapper.eq("to_id",toId);
            }
            String begin = messageQueryDTO.getBegin();
            if(!StringUtils.isEmpty(begin)){
                wrapper.ge("gmt_create",begin);
            }
            String end = messageQueryDTO.getEnd();
            if (!StringUtils.isEmpty(end)){
                wrapper.le("gmt_create",end);
            }
        }
        wrapper.orderByDesc("gmt_create");
        page(page,wrapper);
        long total = page.getTotal();
        List<MessageDO> records = page.getRecords();
        if(records == null){
            return null;
        }
        List<MessageReplyListVO> messageListVOList = new ArrayList<>();
        for (MessageDO record : records) {
            MessageReplyListVO messageListVO = new MessageReplyListVO();
            BeanUtils.copyProperties(record, messageListVO);
            UserDO userDO = userService.getById(record.getFromId());
            messageListVO.setNickname(userDO.getNickname());
            messageListVO.setAvatar(userDO.getAvatar());
            messageListVO.setType(record.getType().getValue());
            messageListVOList.add(messageListVO);
        }

        return new PageResult<>(total,messageListVOList);
    }

    public void hasRead(String messageId) {
        MessageDO messageDO = getById(messageId);
        messageDO.setIsReaded(1);
        updateById(messageDO);
    }

    public int getNotReadNumber() {
        QueryWrapper<MessageDO> wrapper = new QueryWrapper<>();
        wrapper.eq("to_id",MindUtils.getUserId());
        wrapper.eq("is_readed",0);
        int count = count(wrapper);
        return count;
    }

    public void hasReadAll() {
        QueryWrapper<MessageDO> wrapper = new QueryWrapper<>();
        wrapper.eq("to_id",MindUtils.getUserId());
        List<MessageDO> list = list(wrapper);
        for (MessageDO messageDO : list) {
            messageDO.setIsReaded(1);
        }
        updateBatchById(list);
    }

    public String send(MessageSendDTO messageSendDTO) {
        MessageDO messageDO = new MessageDO();
        BeanUtils.copyProperties(messageSendDTO, messageDO);

        //TODO：去重

        //隧道
        TunnelDO tunnelDO = new TunnelDO();
        tunnelDO.setUserId(messageSendDTO.getUserId());
        tunnelDO.setAnotherId(messageSendDTO.getToId());
        //隧道类型与消息类型一致
        tunnelDO.setStatus(TunnelStatusEnum.getByType(messageSendDTO.getType()));
        tunnelDao.save(tunnelDO);

        messageDO.setTunnelId(tunnelDO.getId());
        messageDao.save(messageDO);

        return messageDO.getId();
    }

    public void deleteMessage(MessageDeleteDTO messageDeleteDTO) {
        MessageDO messageDO = messageDao.getById(messageDeleteDTO.getMessageId());

        TunnelDO tunnelDO = tunnelDao.getOne(new QueryWrapper<TunnelDO>().eq("tunnel_id", messageDO.getTunnelId()).eq("user_id", messageDeleteDTO.getUserId()));

        tunnelDao.removeById(tunnelDO);
    }

    public String agree(AgreeDTO agreeDTO) {
        MessageDO messageDO = new MessageDO();
        BeanUtils.copyProperties(agreeDTO, messageDO);

        //隧道
        TunnelDO tunnelDO = new TunnelDO();
        tunnelDO.setUserId(agreeDTO.getUserId());
        tunnelDO.setAnotherId(agreeDTO.getToId());
        tunnelDO.setStatus(TunnelStatusEnum.getByType(agreeDTO.getStatus()));
        tunnelDao.save(tunnelDO);

        messageDO.setTunnelId(tunnelDO.getId());
        messageDao.save(messageDO);

        return messageDO.getId();
    }

    public String reply(MessageReplyDTO messageReplyDTO) {
        MessageDO messageDO = new MessageDO();
        BeanUtils.copyProperties(messageReplyDTO, messageDO);
        messageDao.save(messageDO);

        return messageDO.getId();
    }

    public String letter(MessageLetterDTO messageLetterDTO) {

        TunnelDO one = tunnelDao.getOne(new QueryWrapper<TunnelDO>().eq("user_id", messageLetterDTO.getUserId()).eq("another_id", messageLetterDTO.getToId()));
        //如果之前没有聊过
        if (one == null) {
            MessageDO messageDO = new MessageDO();
            BeanUtils.copyProperties(messageLetterDTO, messageDO);

            //隧道
            TunnelDO tunnelDO = new TunnelDO();
            tunnelDO.setUserId(messageLetterDTO.getUserId());
            tunnelDO.setAnotherId(messageLetterDTO.getToId());
            tunnelDO.setStatus(TunnelStatusEnum.getByType(messageLetterDTO.getType().getType()));
            tunnelDao.save(tunnelDO);

            messageDO.setTunnelId(tunnelDO.getId());
            messageDao.save(messageDO);

            return tunnelDO.getId();//之前没有聊过
        }
        one.setStatus(TunnelStatusEnum.getByType(messageLetterDTO.getType().getType()));
        tunnelDao.save(one);

        return one.getId();
    }

    public PageResult<MessageReplyListVO> display(MessageDisplayDTO messageDisplayDTO) {
        LambdaQueryWrapper<MessageDO> wrapper = new LambdaQueryWrapper<>();
        Optional.of(messageDisplayDTO).map(MessageDisplayDTO::getFromId).ifPresent(fromId -> {
            wrapper.eq(MessageDO::getFromId, fromId);
        });
        Optional.of(messageDisplayDTO).map(MessageDisplayDTO::getToId).ifPresent(toId -> {
            wrapper.eq(MessageDO::getToId, toId);
        });
        Optional.of(messageDisplayDTO).map(MessageDisplayDTO::getType).ifPresent(type -> {
            wrapper.eq(MessageDO::getType, type);
        });
        Optional.of(messageDisplayDTO).map(MessageDisplayDTO::getTunnelId).ifPresent(tunnelId -> {
            wrapper.eq(MessageDO::getTunnelId, tunnelId);
        });
        wrapper.orderByDesc(MessageDO::getGmtCreate);

        List<MessageDO> messageDOS = list(wrapper);

        List<MessageReplyListVO> list = new ArrayList<>();
        for (MessageDO messageDO : messageDOS) {
            MessageReplyListVO messageListVO = new MessageReplyListVO();
            BeanUtils.copyProperties(messageDO, messageListVO);
            DateFormat dateFormat = new SimpleDateFormat("HH:mm");
            String date = dateFormat.format(messageDO.getGmtCreate());
            messageListVO.setGmtCreate(date);
            UserDO userDO = userService.getById(messageDO.getFromId());
            messageListVO.setNickname(userDO.getNickname());
            messageListVO.setAvatar(userDO.getAvatar());

            list.add(messageListVO);
        }

        Integer total = lambdaQuery().eq(MessageDO::getFromId, messageDisplayDTO.getFromId()).eq(MessageDO::getToId, messageDisplayDTO.getToId()).count();

        return new PageResult<>(total, list);

    }

    public PageResult<MessageListVO> listUser(MessageListDTO messageListDTO) {
        LambdaQueryWrapper<MessageDO> wrapper = new LambdaQueryWrapper<>();

        Optional.of(messageListDTO).map(MessageListDTO::getFromId).ifPresent(fromId -> {
            wrapper.eq(MessageDO::getFromId, fromId);
        });
        wrapper.orderByDesc(MessageDO::getGmtCreate);

        List<MessageDO> messageDOS = list(wrapper);

        List<MessageListVO> list = new ArrayList<>();
        for (MessageDO messageDO : messageDOS) {
            MessageListVO messageListVO = new MessageListVO();
            BeanUtils.copyProperties(messageDO, messageListVO);
            list.add(messageListVO);
        }

        Integer total = lambdaQuery().eq(MessageDO::getToId, messageListDTO.getFromId()).count();

        return new PageResult<>(total, list);

    }
}
